#ifndef _core_switch_detail_case_invoker_hpp_
#define _core_switch_detail_case_invoker_hpp_

/** \file case_invoker.hpp
 *  \author Adrian Schweizer
 *  \created  $Mo 11 Feb 08:33:01 pm CET 2008 schwadri@SchwadriLaptop.local$
 *  \modified $Mo 11 Feb 11:50:11 pm CET 2008 schwadri@SchwadriLaptop.local$
 */

#include <boost/mpl/deref.hpp>

namespace core {

    template <typename Case, typename Label, typename Offset>
        struct case_invoker
        {
            typedef case_invoker<Case,Label,Offset> type;

            typedef typename Case::functor  functor;
            typedef Label                   label;
            typedef void                    return_type;

            template <typename Cases>
                case_invoker(const Cases& cs)
                //FIXME: ugly hack.
                :   m_f(**reinterpret_cast<const functor*const*>(reinterpret_cast<const char*>(&cs)+sizeof(void*)*Offset::value))
                {
                    std::cout << "offset: "<<Offset::value <<std::endl;
                }


                return_type operator()() const
                {
                    return call(label());
                }

            template <typename Key>
                return_type operator()(Key key) const
                {
                    return call(/*boost::mpl::integral_c<Key,key>()*/key);
                }

        private:

            /*struct invoke_with_nothing
            {
                template <typename Key>
                    static return_type invoke(functor f, Key key)
                    {
                        return f();
                    }
            };

            struct invoke_with_key
            {
                template <typename Key>
                    static return_type invoke(functor f, Key key)
                    {
                        return f(key::value);
                    }
            };

            struct invoke_with_label
            {
                template <typename Key>
                    static return_type invoke(functor f, Key key)
                    {
                        return f(label());
                    }
            };*/

            template <typename Key>
                return_type call(Key key) const
                {
                    /*using namespace boost::mpl;
                    //select the invocation method
                    typedef typename boost::function_types::parameter_types<Functor>::type  func;
                    typedef typename switch_<
                                        func,
                                        pair<,invoke_with_label>,   //if 1st param is integral type
                                        pair<,invoke_with_key>,     //if template method
                                        pair<,invoke_with_nothing>, //takes no parameters
                                        >::type type;
                    */
                    //return type::invoke(m_f,key);
                    return m_f(key);
                }

            const functor&  m_f;
        };
}


#endif // _core_switch_detail_case_invoker_hpp_
